package ija.controller;

import ija.model.CheckersModel;
import ija.model.types.FigureColor;
import ija.model.types.FigureRoute;
import ija.model.types.GameMoves;
import ija.xls.notation.DeskCoordinate;
import ija.xls.notation.GameMove;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Trida je zodpovedna za praci s pravidly pro hru dama. Umi ziskavat vsechny
 * tahy, validovat tahy, atd.
 * 
 * @author Radek Necas, xnecas18
 */
public class CheckersRuller {

    protected CheckersController controller;
    protected CheckersModel model;
    protected List<GameMoves> allmoves;

    /**
     * Konstruktor vytvori novou instanci tridy
     * 
     * @param controller
     *            kontroler hry dama
     * @param model
     *            model hry dama
     */
    public CheckersRuller(CheckersController controller, CheckersModel model) {
        this.controller = controller;
        this.model = model;
    }

    /**
     * Metoda slouzi pro ziskani vsech tahu hrace s danou barvou
     * 
     * @param c
     *            barva, pro kterou se budou tahy ziskavat
     * @return seznam vsech tahu vsech figurek dane barvy
     */
    public List<GameMoves> getAllMoves(FigureColor c) {
        return this.model.getDesk().getAllMoves(c);
    }

    public void storeAllMoves(FigureColor c) {
        this.allmoves = this.getAllMoves(c);
    }

    public String chooseRandomMove() {
        if ((this.allmoves == null) || this.allmoves.isEmpty()) {
            return null;
        }

        ArrayList<String> possibleMoves = new ArrayList<String>();
        Integer moveCount = 0;
        Integer randomIndex = 0;

        for (GameMoves move : this.allmoves) {
            for (FigureRoute r : move.getPositions()) {
                if (r.getText().length() > 2) {
                    possibleMoves.add(r.getText());
                    System.out.println("->" + r.getText());
                    moveCount++;
                }
            }
        }
        randomIndex = (int) (Math.random() * moveCount);
        return possibleMoves.get(randomIndex);
    }

    /**
     * Metoda zjisti, zda hrac uvedene barvy muze provest testovany tah
     * 
     * @param gameMove
     *            testovany tah
     * @param c
     *            barva hrace, pro ktereho se test provadi
     * @return vysledek testu, true - OK, false - CHYBA
     */
    public boolean validateGameMove(GameMove gameMove, FigureColor c) {
        List<GameMoves> allMoves = this.getAllMoves(c);
        GameMoves discoverMoves = null;
        for (GameMoves gm : allMoves) {
            if (gm.getPositions().getRoot().getData().getCoordinate()
                    .equals(gameMove.getFirstPosition())) {
                discoverMoves = gm;
                break;
            }
        }

        if (discoverMoves != null) {
            LinkedList<FigureRoute> routes = new LinkedList<>();
            for (DeskCoordinate dc : gameMove) {
                routes.addLast(new FigureRoute(dc, ""));
            }

            return ((discoverMoves.getOperationType() == gameMove.getOperation()) && discoverMoves
                    .getPositions().isInside(routes));
        }

        return false;
    }
}
